package api

import (
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"net/http"
	"todo-list/constants"
	"todo-list/service"
	"todo-list/types"
	"todo-list/utils/responses"
)

func ShowTaskHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		l := service.GetTaskSrv()
		var req types.ShowTaskReq
		err := ctx.ShouldBindUri(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		task, err := l.ShowTaskInfo(ctx, &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeShowTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccessWithData(*task))
	}
}

func ViewPublicTaskHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		l := service.GetTaskSrv()
		var req types.ListTaskReq
		err := ctx.ShouldBindQuery(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		req.PublicOnly = true
		dataList, err := l.ViewPublicTask(ctx.Request.Context(), &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeFindTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccessWithData(*dataList))
	}
}

func ViewSelfTaskHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		userId := getUserId(ctx)
		l := service.GetTaskSrv()
		var req types.ListTaskReq
		err := ctx.ShouldBindQuery(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		dataList, err := l.ViewSelfTask(ctx.Request.Context(), userId, &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeFindTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccessWithData(*dataList))
	}
}

func CreateTaskHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		userId := getUserId(ctx)
		l := service.GetTaskSrv()
		var req types.CreateTaskReq
		err := ctx.ShouldBindJSON(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		err = l.CreateTask(ctx.Request.Context(), userId, &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CreateTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccess())
	}
}

func UpdateTaskHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		userId := getUserId(ctx)
		l := service.GetTaskSrv()
		var req types.UpdateTaskReq
		err := ctx.ShouldBindUri(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		err = ctx.ShouldBindJSON(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		err = l.UpdateTask(ctx.Request.Context(), userId, &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.UpdateTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccess())
	}
}

func UpdateTaskStatusOrPublicBatchHandler() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		userId := getUserId(ctx)
		l := service.GetTaskSrv()
		var req types.UpdateTaskBatchReq
		err := ctx.ShouldBindJSON(&req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.CodeInvalidParams))
			return
		}
		err = l.UpdateStatusOrPublicBatch(ctx.Request.Context(), userId, &req)
		if err != nil {
			logrus.Errorln(err.Error())
			ctx.JSON(http.StatusInternalServerError, responses.RespError(err, constants.UpdateTaskFail))
			return
		}
		ctx.JSON(http.StatusOK, responses.RespSuccess())
	}
}
